<?php
/**
 * quick_curd
 * ============================================================================
 * 版权所有 2024-2099 www.wltx666.com，并保留所有权利。
 * 网站地址: https://www.wltx666.com
 * ============================================================================
 * Author: 草上飞
 * Email: wei@alipay16.cn
 * QQ: 2719875001
 * Date: 2025/7/17
 * 描述:
 */
// 开启输出缓冲
ob_start();
error_reporting(0); // 安装阶段关闭错误显示
// 注册全局异常捕获
set_exception_handler(function($e) {
    exit_response([
        'code' => 500,
        'message' => '系统异常: ' . $e->getMessage()
    ]);
});
header('Content-Type:text/html; charset=utf-8');
$rootDir = __DIR__ . '/../';
function exit_response($data)
{
     // 清理缓冲区
    while (ob_get_level() > 0) {
        ob_end_clean();
    }

    header('Content-Type:application/json');
    echo json_encode($data, JSON_UNESCAPED_UNICODE);
    exit;
}

if (is_file($rootDir . '/.env')) {
    exit_response([
        'code' => 500,
        'message' => '已安装，请勿重复安装,如果需重新安装，请删除文件:' . $rootDir . '.env',
    ]);
    exit;
}
$sqlFile = $rootDir . '/install/quick_curd.sql';
if (!is_file($sqlFile)) {
    exit_response([
        'code' => 500,
        'message' => '缺少数据库文件,请检查数据库文件是否存在',
    ]);
}

// 处理表单提交
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    //跳过安装
    if (!empty($_POST['jump'])) {
        file_put_contents($rootDir . '/.env', '#这里的配置会覆盖docker环境变量的值哦');
        exit_response([
            'code' => 200,
            'message' => '跳过安装成功',
        ]);
    }

    $dbName = trim($_POST['db_name'] ?? '');
    $dbPrefix = trim($_POST['db_prefix'] ?? '');
    $dbCharset = trim($_POST['db_charset'] ?? "");
    $dbHost = trim($_POST['db_host'] ?? "");
    $dbUser = trim($_POST['db_user'] ?? '');
    $dbPwd = trim($_POST['db_pwd'] ?? '');
    $dbPort = intval($_POST['db_port'] ?? '3306');
    if (!$dbName) {
        exit_response([
            'code' => 500,
            'message' => '请填写数据库名称',
        ]);
    }
    if (!$dbCharset) {
        exit_response([
            'code' => 500,
            'message' => '请填写数据库字符集',
        ]);
    }
    if (!$dbHost) {
        exit_response([
            'code' => 500,
            'message' => '请填写数据库地址',
        ]);
    }
    if (!$dbUser) {
        exit_response([
            'code' => 500,
            'message' => '请填写数据库用户名',
        ]);
    }
    if (!$dbPwd) {
        exit_response([
            'code' => 500,
            'message' => '请填写数据库密码',
        ]);
    }


    // 使用PDO连接数据库并执行SQL文件
     $logFile = __DIR__ . '/install' . date('Y-m-d') . '.log';
    try {
        $pdo = new PDO("mysql:host=$dbHost;port=$dbPort;charset=" . $dbCharset, $dbUser, $dbPwd);



        $pdo->exec("SET NAMES " . $dbCharset);
        $pdo->exec("CREATE DATABASE IF NOT EXISTS `$dbName` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;");
        $pdo->exec("USE `$dbName`;");

        // 执行SQL文件
        $sqlContent = file_get_contents($sqlFile);

        // 去除单行注释
        $sqlContent = preg_replace('/--.*$/m', '', $sqlContent);
        $sqlContent = preg_replace('/#.*$/m', '', $sqlContent);
        // 替换 前缀
        $sqlContent = str_replace('`bs_', '`' . $dbPrefix, $sqlContent);

        // 去除多行注释
        $sqlContent = preg_replace('~/\*.*?\*/~s', '', $sqlContent);

        // 分割 SQL 语句
        $statements = array_filter(array_map('trim', explode(';', $sqlContent)));



        foreach ($statements as $stmt) {
            // 跳过创建数据库和使用数据库的SQL
            if (str_starts_with($stmt, 'CREATE DATABASE') || str_starts_with($stmt, 'use')) {
                continue;
            }
            if (!empty($stmt)) {
                try {
                    $pdo->exec($stmt);
                } catch (PDOException $e) {

                    exit_response([
                        'code' => 500,
                        'message' => "执行失败: " . $e->getMessage() . "\n在语句:\n$stmt\n",
                    ]);
                }
            }
        }

    } catch (PDOException $e) {
        file_put_contents($logFile, $e->getMessage(), FILE_APPEND);
        exit_response([
            'code' => 500,
            'message' => '数据库连接失败，请检查配置或网络',
        ]);
    } catch (Exception $e) {
        exit_response([
            'code' => 500,
            'message' => '数据库连接正常，但查询失败',
        ]);
    }
    // 创建.env文件
    $envContent = <<<EOT
DB_DRIVER  = mysql
DB_TYPE = mysql
DB_HOST = $dbHost
DB_NAME = $dbName
DB_USER = $dbUser
DB_PASSWORD = $dbPwd
DB_PORT = $dbPort
DB_CHARSET = $dbCharset
DB_DEBUG = true
DB_PREFIX = $dbPrefix
EOT;

    $jwt_key = md5(uniqid(rand(), true));

    $envContent = str_replace('$database', $envContent, file_get_contents($rootDir . '/install/env.tpl'));
    $envContent = str_replace('$jwt_key', $jwt_key, $envContent);
    file_put_contents($rootDir . '/.env', $envContent);
    exit_response([
        'code' => 200,
        'message' => '安装成功',
    ]);
}
?>

<!doctype html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>安装快速CURD系统</title>
    <link rel="stylesheet" href="./static/lib/bootstrap4.6.2/bootstrap.min.css">
    <style>
        .container{
            margin-top: 100px;
            padding: 20px;
        }
        .notice {
            background-color: #f8f9fa;
            padding: 1rem;
            margin-bottom: 1rem;
            border-radius: .25rem;
            color: red;
        }
    </style>
</head>
<body>
<div class="container mt-5">
    <h1 class="text-center mb-4">安装快速一键CURD系统</h1>
    <div class="notice">

        <p>
            如果不想自动安装，请在网站根目录中创建.env文件，内容参考.example.env文件。.env如果没有内容对应的变量内容，程序会用docker容器的环境变量。</p>
        <p>如果需重新安装，请删除文件：网站根目录中的.env</p>
        <p>！！！此操作会创建数据库，并导入数据库文件，会删除旧数据，请确认无误后提交，适用首次安装的用户。</p>
        <p>！！！使用云端数据库或者远程数据库建议直接自己创建.env文件，配置后刷新页面。</p>
        <p>！！！每次重启或者重新构建容器，.env都会被清理，请自行配置.env文件。</p>
        <p>！！！请确认数据库已启动，并配置好数据库用户名和密码(默认root:root)，如果操作失败请自己配置.env文件。</p>
        <p>！！！不会搭建请发邮件或者联系作者微信（woyekeyiha）：wei@alipay16.cn（备注：quick_curd）。</p>
        <p> 已有数据库或者用环境变量配置.env文件，请跳过！
            <button class="btn btn-success btn-sm" onclick="jump_install()">跳过安装</button>
        </p>
    </div>
    <div class="needs-validation">
        <div class="form-group">
            <label for="db_host">数据库地址：</label>
            <input type="text" id="db_host" value="quick_curd_mysql" name="db_host" class="form-control" required>
            <div class="invalid-feedback">请输入数据库地址。</div>
            <small class="form-text text-muted">默认为quick_curd_mysql这个容器的mysql数据库</small>
        </div>
        <div class="form-group">
            <label for="db_name">数据库名称：</label>
            <input type="text" id="db_name" value="quick_curd" name="db_name" class="form-control" required>
            <div class="invalid-feedback">请输入数据库名称。</div>
        </div>
        <div class="form-group">
            <label for="db_user">用户名：</label>
            <input type="text" id="db_user" value="root" name="db_user" class="form-control" required>
            <div class="invalid-feedback">请输入数据库用户名。</div>
        </div>
        <div class="form-group">
            <label for="db_pwd">密码：</label>
            <input type="password" id="db_pwd" name="db_pwd" value="root" class="form-control" required>
            <div class="invalid-feedback">请输入数据库密码。</div>
        </div>
        <div class="form-group">
            <label for="db_port">端口：</label>
            <input type="text" id="db_port" value="3306" name="db_port" class="form-control" required>
            <div class="invalid-feedback">请输入数据库端口。</div>
            <small class="form-text text-muted">默认3306</small>
        </div>

        <div class="form-group">
            <label for="db_prefix">表前缀：</label>
            <input type="text" id="db_prefix" value="bs_" name="db_prefix" class="form-control" required>
            <div class="invalid-feedback">请输入表前缀。</div>
        </div>

        <div class="form-group">
            <label for="db_charset">字符编码：</label>
            <select id="db_charset" name="db_charset" class="form-control">
                <option value="utf8mb4">utf8mb4</option>
                <option value="utf8">UTF-8</option>
                <!-- <option value="utf8mb4_unicode_ci">utf8mb4（带4字节字符，带Unicode编码）</option>-->
            </select>
            <div class="invalid-feedback">请输入字符编码。</div>
        </div>

        <button type="submit" id="installBtn" class="btn btn-primary btn-block">开始安装</button>

    </div>
</div>

<script src="./static/lib/jquery/jquery.min.js"></script>
<script>
    function jump_install() {
        var confirm = window.confirm("请确认是否跳过安装？");
        if (!confirm) {
            return false;
        }
        $.ajax({
            url: "install.php",
            type: 'post',
            dataType: 'json',
            data: {
                jump: true
            },
            success: function (data) {
                if (data.code === 200) {
                    window.location.href = '/admin';
                } else {
                    alert(data.message);
                }
            },
        })
    }

    $(document).ready(function () {
        $("#installBtn").click(function () {
            let confirm = window.confirm("请确认是否安装？");
            if (!confirm) {
                return false;
            }
            const btn = document.getElementById('installBtn');
            btn.disabled = true;
            btn.textContent = '安装中，请勿重复提交...';
            var db_host = $("#db_host").val();
            var db_name = $("#db_name").val();
            var db_prefix = $("#db_prefix").val();
            var db_charset = $("#db_charset").val();
            var db_user = $("#db_user").val();
            var db_pwd = $("#db_pwd").val();
            var db_port = $("#db_port").val();
            if (!db_host || !db_name || !db_prefix || !db_charset) {
                alert('请填写完整信息！');
                return false;
            }
            try {
                $.ajax({
                    type: "post",
                    url: "install.php",
                    dataType: 'json',
                    data: {
                        db_host: db_host,
                        db_name: db_name,
                        db_prefix: db_prefix,
                        db_charset: db_charset,
                        db_user: db_user,
                        db_pwd: db_pwd,
                        db_port: db_port,
                    },
                    success: function (data) {
                        console.log(data);
                        if (data.code == 200) {
                            alert(data.message);
                            window.location.href = '/admin';
                        } else {
                            alert(data.message);
                        }
                    },
                    error: function (xhr, status, error) {
                        console.error('AJAX错误:', status, error);
                        console.error('服务器响应:', xhr.responseText);

                        // 显示详细错误信息
                        let msg = "安装失败: ";
                        if (xhr.responseText) {
                            msg += "\n服务器返回:\n" + xhr.responseText.substring(0, 500);
                        }
                        alert(msg);

                        btn.disabled = false;
                        btn.textContent = '开始安装';
                    },
                    complete: function () {
                        btn.disabled = false;
                        btn.textContent = '开始安装';
                    }
                })
            } catch (e) {
                console.log('err', e);
            }

        })
    })
</script>
</body>
</html>
